/*****************************************************************************************
   
   Copyright (c) Microsoft Corporation. All rights reserved.

   Use of this code sample is subject to the terms of the Microsoft
   Permissive License, a copy of which should always be distributed with
   this file.  You can also access a copy of this license agreement at:
   http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx

 ****************************************************************************************/

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace GrooveWebServicesV12Controls
{
	/// <summary>
	/// Summary description for UserControl1.
	/// </summary>
	[System.Runtime.InteropServices.Guid("C11FEC7B-1237-35BA-B6FF-E196F1277379")]
	[System.Drawing.ToolboxBitmapAttribute(typeof(TreeViewNavigator), "TreeViewNavigator.ico")]
	public class TreeViewNavigator : System.Windows.Forms.UserControl
	{
		#region COM Registration Functions
		
		//  For more information, see Adam Nathan's book ".NET and COM", pp 471-477
		[System.Runtime.InteropServices.ComRegisterFunction]
		private static void ComRegisterFunction(System.Type i_Type)
		{
			Microsoft.Win32.RegistryKey CLSIDRegistryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("CLSID\\" + i_Type.GUID.ToString("B"), true);
			CLSIDRegistryKey.CreateSubKey("Control");
			CLSIDRegistryKey.CreateSubKey("Implemented Categories\\{40FC6ED4-2438-11CF-A3DB-080036F12502}");
			
			Microsoft.Win32.RegistryKey MiscStatusRegistryKey = CLSIDRegistryKey.CreateSubKey("MiscStatus");
			MiscStatusRegistryKey.SetValue("","131457");

			Microsoft.Win32.RegistryKey TypeLibRegistryKey = CLSIDRegistryKey.CreateSubKey("TypeLib");
			string TypeLibGuid = System.Runtime.InteropServices.Marshal.GetTypeLibGuidForAssembly(i_Type.Assembly).ToString("B");
			TypeLibRegistryKey.SetValue("", TypeLibGuid);

			string Version = i_Type.Assembly.GetName().Version.Major.ToString() + "." + i_Type.Assembly.GetName().Version.Minor.ToString();
			if (Version == "0.0")
				Version = "1.0";

			Microsoft.Win32.RegistryKey VersionRegistryKey = CLSIDRegistryKey.CreateSubKey("Version");
			VersionRegistryKey.SetValue("", Version);

			CLSIDRegistryKey.Close();
		}

		[System.Runtime.InteropServices.ComUnregisterFunction]
		private static void ComUnregisterFunction(System.Type i_Type)
		{
			try
			{
				Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree("CLSID\\" + i_Type.GUID.ToString("B"));
			}
			catch (ArgumentException)
			{
				//  Ignore exception thrown if key doesn't exist
			}
		}

		#endregion

		private GrooveWebServicesV12Helpers.Context m_Context;
		private GrooveWebServicesV12Helpers.Identity m_CurrentIdentity;

		private System.Collections.SortedList m_AccountTreeNodeSortedList;
		private System.Collections.SortedList m_IdentityTreeNodeSortedList;
		private System.Collections.SortedList m_SpaceTreeNodeSortedList;
		private System.Collections.SortedList m_ToolTreeNodeSortedList;
		
		private delegate void AddSpaceTreeNodeDelegate(System.Windows.Forms.TreeNodeCollection i_TreeNodeCollection, GrooveWebServicesV12Helpers.Space i_Space);
		private delegate void RenameSpaceTreeNodeDelegate(string i_SpaceURI, string i_SpaceName);

		private delegate void AddToolTreeNodeDelegate(System.Windows.Forms.TreeNodeCollection i_TreeNodeCollection, GrooveWebServicesV12Helpers.Tool i_Tool);
		private delegate void RenameToolTreeNodeDelegate(string i_ToolURI, string i_ToolName);
		
		private delegate void RemoveTreeNodeDelegate(System.Collections.SortedList i_SortedList, string i_URI);

		private AddSpaceTreeNodeDelegate m_AddSpaceTreeNodeDelegate;
		private RenameSpaceTreeNodeDelegate m_RenameSpaceTreeNodeDelegate;
		
		private AddToolTreeNodeDelegate m_AddToolTreeNodeDelegate;
		private RenameToolTreeNodeDelegate m_RenameToolTreeNodeDelegate;

		private RemoveTreeNodeDelegate m_RemoveTreeNodeDelegate;

		private System.Windows.Forms.ImageList imageList1;
		public System.Windows.Forms.TreeView TreeView;
		private System.ComponentModel.IContainer components;

		private System.Windows.Forms.ContextMenu m_ContextMenu;
		
		private System.EventHandler m_ToolMenuEventHandler;
		private System.Windows.Forms.MenuItem m_ViewToolMenuItem;
		private System.Windows.Forms.MenuItem m_ViewToolPropertiesMenuItem;
		
		private System.EventHandler m_SpaceMenuEventHandler;
		private System.Windows.Forms.MenuItem m_ViewSpaceMenuItem;
		private System.Windows.Forms.MenuItem m_ViewSpacePropertiesMenuItem;

		private System.EventHandler m_IdentityMenuEventHandler;
		private System.Windows.Forms.MenuItem m_EditVCardMenuItem;

		private System.EventHandler m_AccountMenuEventHandler;
		private System.Windows.Forms.MenuItem m_ViewAccountSetupMenuItem;
		private System.Windows.Forms.MenuItem m_ViewAboutGrooveDialogMenuItem;
		private System.Windows.Forms.MenuItem m_ViewLicensesDialogMenuItem;
		private System.Windows.Forms.MenuItem m_ViewCommunicationsMenuItem;
		private System.Windows.Forms.MenuItem m_ViewPreferencesMenuItem;

		public bool m_AlwaysShowAccounts;
		public bool m_AlwaysShowIdentities;

		private const long HIDE_FILES_TOOLS = 0x1;
		private const long HIDE_DISCUSSION_TOOLS = 0x2;
		private const long HIDE_CALENDAR_TOOLS = 0x4;
		private const long HIDE_FORMS_TOOLS = 0x10;

		private long m_HideToolsBitMask;

		private string m_InitialIdentityURI = null;
		private string m_InitialSpaceURI = null;

		public TreeViewNavigator()
		{
			int_TreeViewNavigator(null);
		}

		public TreeViewNavigator(GrooveWebServicesV12Helpers.Context i_Context)
		{
			int_TreeViewNavigator(i_Context);
		}

		public void int_TreeViewNavigator(GrooveWebServicesV12Helpers.Context i_Context)
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();

			if (!this.DesignMode)
			{
				TreeView.Sorted = true;

				if (i_Context == null)
					m_Context = new GrooveWebServicesV12Helpers.Context();
				else
					m_Context = i_Context;

				m_AccountTreeNodeSortedList = new System.Collections.SortedList();				
				m_IdentityTreeNodeSortedList = new System.Collections.SortedList();
				m_SpaceTreeNodeSortedList = new System.Collections.SortedList();
				m_ToolTreeNodeSortedList = new System.Collections.SortedList();

				//  Create context menu and menu items
				m_ToolMenuEventHandler = new System.EventHandler(ToolMenu_OnClick);
				m_ViewToolMenuItem = new System.Windows.Forms.MenuItem("View...", m_ToolMenuEventHandler);
				m_ViewToolPropertiesMenuItem = new System.Windows.Forms.MenuItem("Properties...", m_ToolMenuEventHandler);

				m_SpaceMenuEventHandler = new System.EventHandler(SpaceMenu_OnClick);
				m_ViewSpaceMenuItem = new System.Windows.Forms.MenuItem("View...", m_SpaceMenuEventHandler);
				m_ViewSpacePropertiesMenuItem = new System.Windows.Forms.MenuItem("Properties...", m_SpaceMenuEventHandler);

				m_IdentityMenuEventHandler = new System.EventHandler(IdentityMenu_OnClick);
				m_EditVCardMenuItem = new System.Windows.Forms.MenuItem("Edit VCard...", m_IdentityMenuEventHandler);

				m_AccountMenuEventHandler = new System.EventHandler(AccountMenu_OnClick);
				m_ViewAccountSetupMenuItem = new System.Windows.Forms.MenuItem("Account Setup...", m_AccountMenuEventHandler);
				m_ViewAboutGrooveDialogMenuItem = new System.Windows.Forms.MenuItem("About Groove...", m_AccountMenuEventHandler);
				m_ViewLicensesDialogMenuItem = new System.Windows.Forms.MenuItem("Licenses...", m_AccountMenuEventHandler);
				m_ViewCommunicationsMenuItem = new System.Windows.Forms.MenuItem("Communications...", m_AccountMenuEventHandler);
				m_ViewPreferencesMenuItem = new System.Windows.Forms.MenuItem("Preferences...", m_AccountMenuEventHandler);
				
				m_ContextMenu = new System.Windows.Forms.ContextMenu();

				//  Initialize delegates
				m_AddSpaceTreeNodeDelegate = new GrooveWebServicesV12Controls.TreeViewNavigator.AddSpaceTreeNodeDelegate(AddSpaceTreeNode);
				m_RenameSpaceTreeNodeDelegate = new GrooveWebServicesV12Controls.TreeViewNavigator.RenameSpaceTreeNodeDelegate(RenameSpaceTreeNode);
				m_AddToolTreeNodeDelegate = new GrooveWebServicesV12Controls.TreeViewNavigator.AddToolTreeNodeDelegate(AddToolTreeNode);
				m_RenameToolTreeNodeDelegate = new GrooveWebServicesV12Controls.TreeViewNavigator.RenameToolTreeNodeDelegate(RenameToolTreeNode);
				m_RemoveTreeNodeDelegate = new GrooveWebServicesV12Controls.TreeViewNavigator.RemoveTreeNodeDelegate(RemoveTreeNode);
			}
		}

		public bool AlwaysShowAccounts
		{
			get
			{
				return m_AlwaysShowAccounts;
			}
			set
			{
				m_AlwaysShowAccounts = value;

				if (this.DesignMode)
					PopulateTreeView();
			}
		}

		public bool AlwaysShowIdentities
		{
			get
			{
				return m_AlwaysShowIdentities;
			}
			set
			{
				m_AlwaysShowIdentities = value;

				if (this.DesignMode)
					PopulateTreeView();
			}
		}

		public bool HideFilesTools
		{
			get
			{
				return ((m_HideToolsBitMask & HIDE_FILES_TOOLS) == HIDE_FILES_TOOLS);
			}
			set
			{
				if (value)
					m_HideToolsBitMask |= HIDE_FILES_TOOLS;
				else
					m_HideToolsBitMask &= ~HIDE_FILES_TOOLS;

				if (this.DesignMode)
					PopulateTreeView();
			}
		}

		public bool HideDiscussionTools
		{
			get
			{
				return ((m_HideToolsBitMask & HIDE_DISCUSSION_TOOLS) == HIDE_DISCUSSION_TOOLS);
			}
			set
			{
				if (value)
					m_HideToolsBitMask |= HIDE_DISCUSSION_TOOLS;
				else
					m_HideToolsBitMask &= ~HIDE_DISCUSSION_TOOLS;

				if (this.DesignMode)
					PopulateTreeView();
			}
		}

		public bool HideCalendarTools
		{
			get
			{
				return ((m_HideToolsBitMask & HIDE_CALENDAR_TOOLS) == HIDE_CALENDAR_TOOLS);
			}
			set
			{
				if (value)
					m_HideToolsBitMask |= HIDE_CALENDAR_TOOLS;
				else
					m_HideToolsBitMask &= ~HIDE_CALENDAR_TOOLS;

				if (this.DesignMode)
					PopulateTreeView();
			}
		}

		public bool HideFormsTools
		{
			get
			{
				return ((m_HideToolsBitMask & HIDE_FORMS_TOOLS) == HIDE_FORMS_TOOLS);
			}
			set
			{
				if (value)
					m_HideToolsBitMask |= HIDE_FORMS_TOOLS;
				else
					m_HideToolsBitMask &= ~HIDE_FORMS_TOOLS;

				if (this.DesignMode)
					PopulateTreeView();
			}
		}

		public void SelectIdentity(string i_IdentityURI, bool i_Expand, bool i_SelectFirstChildNode)
		{
			//  If identity uris match, just exit now
			if ((m_CurrentIdentity != null) && (m_CurrentIdentity.URI == i_IdentityURI))
				return;

			//  Check for existing node, if not found just exit now
			GrooveWebServicesV12Controls.IdentityTreeNode IdentityTreeNode = (GrooveWebServicesV12Controls.IdentityTreeNode)m_IdentityTreeNodeSortedList[i_IdentityURI];
			if (IdentityTreeNode == null)
				return;

			m_CurrentIdentity = IdentityTreeNode.Identity;

			//  Expand tree nodes first (must do this or get funky focus issues)
			if (i_Expand || i_SelectFirstChildNode)
				IdentityTreeNode.Expand();

			//  Set selected tree node
			if (i_SelectFirstChildNode && (IdentityTreeNode.Nodes.Count > 0))
				TreeView.SelectedNode = IdentityTreeNode.FirstNode;
			else
				TreeView.SelectedNode = IdentityTreeNode;
		}

		public void SelectSpace(string i_SpaceURI, bool i_Expand, bool i_SelectFirstChildNode)
		{
			//  Check for existing node, if not found just exit now
			GrooveWebServicesV12Controls.SpaceTreeNode SpaceTreeNode = (GrooveWebServicesV12Controls.SpaceTreeNode)m_SpaceTreeNodeSortedList[i_SpaceURI];
			if (SpaceTreeNode == null)
				return;

			TreeView.SelectedNode = SpaceTreeNode;

			//  Expand tree nodes first (must do this or get funky focus issues)
			if (i_Expand || i_SelectFirstChildNode)
				SpaceTreeNode.Expand();

			//  Set selected tree node
			if (i_SelectFirstChildNode && (SpaceTreeNode.Nodes.Count > 0))
				TreeView.SelectedNode = SpaceTreeNode.FirstNode;
			else
				TreeView.SelectedNode = SpaceTreeNode;
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if( components != null )
					components.Dispose();

				
				if (m_IdentityTreeNodeSortedList.Count > 0)
				{
					//  Unsubscribe for space events for each identity in
					//  sort listed
					foreach (System.Collections.DictionaryEntry DictionaryEntry in m_IdentityTreeNodeSortedList)
					{
						GrooveWebServicesV12Controls.IdentityTreeNode IdentityTreeNode = (GrooveWebServicesV12Controls.IdentityTreeNode)DictionaryEntry.Value;
						
						IdentityTreeNode.Identity.OnSpaceAddedEvent -= new GrooveWebServicesV12Helpers.Identity.OnSpaceAddedDelegate(Identity_OnSpaceAdded);
						IdentityTreeNode.Identity.OnSpaceRenamedEvent -= new GrooveWebServicesV12Helpers.Identity.OnSpaceRenamedDelegate(Identity_OnSpaceRenamed);
						IdentityTreeNode.Identity.OnSpaceRemovedEvent -= new GrooveWebServicesV12Helpers.Identity.OnSpaceRemovedDelegate(Identity_OnSpaceRemoved);
					}
				}
				else
				{
					if (m_CurrentIdentity != null)
					{
						//  Unsubscribe for space events for current identity
						m_CurrentIdentity.OnSpaceAddedEvent -= new GrooveWebServicesV12Helpers.Identity.OnSpaceAddedDelegate(Identity_OnSpaceAdded);
						m_CurrentIdentity.OnSpaceRenamedEvent -= new GrooveWebServicesV12Helpers.Identity.OnSpaceRenamedDelegate(Identity_OnSpaceRenamed);
						m_CurrentIdentity.OnSpaceRemovedEvent -= new GrooveWebServicesV12Helpers.Identity.OnSpaceRemovedDelegate(Identity_OnSpaceRemoved);
					}
				}

				//  Unsubscribe for tool events
				foreach (System.Collections.DictionaryEntry DictionaryEntry in m_SpaceTreeNodeSortedList)
				{
					GrooveWebServicesV12Controls.SpaceTreeNode SpaceTreeNode = (GrooveWebServicesV12Controls.SpaceTreeNode)DictionaryEntry.Value;

					SpaceTreeNode.Space.OnToolAddedEvent -= new GrooveWebServicesV12Helpers.Space.OnToolAddedDelegate(Space_OnToolAdded);
					SpaceTreeNode.Space.OnToolRenamedEvent -= new GrooveWebServicesV12Helpers.Space.OnToolRenamedDelegate(Space_OnToolRenamed);
					SpaceTreeNode.Space.OnToolRemovedEvent -= new GrooveWebServicesV12Helpers.Space.OnToolRemovedDelegate(Space_OnToolRemoved);
				}

				//  Clear sorted lists
				m_AccountTreeNodeSortedList.Clear();
				m_IdentityTreeNodeSortedList.Clear();
				m_SpaceTreeNodeSortedList.Clear();
				m_ToolTreeNodeSortedList.Clear();
			}
			base.Dispose( disposing );
		}

		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(TreeViewNavigator));
			this.TreeView = new System.Windows.Forms.TreeView();
			this.imageList1 = new System.Windows.Forms.ImageList(this.components);
			this.SuspendLayout();
			// 
			// TreeView
			// 
			this.TreeView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
			this.TreeView.Dock = System.Windows.Forms.DockStyle.Fill;
			this.TreeView.HideSelection = false;
			this.TreeView.ImageList = this.imageList1;
			this.TreeView.Location = new System.Drawing.Point(0, 0);
			this.TreeView.Name = "TreeView";
			this.TreeView.SelectedImageIndex = 6;
			this.TreeView.Size = new System.Drawing.Size(256, 344);
			this.TreeView.TabIndex = 0;
			this.TreeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.TreeView_MouseDown);
			this.TreeView.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.TreeView_BeforeSelect);
			this.TreeView.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.TreeView_BeforeExpand);
			// 
			// imageList1
			// 
			this.imageList1.ColorDepth = System.Windows.Forms.ColorDepth.Depth24Bit;
			this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
			this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
			this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
			// 
			// TreeViewNavigator
			// 
			this.Controls.Add(this.TreeView);
			this.Name = "TreeViewNavigator";
			this.Size = new System.Drawing.Size(256, 344);
			this.Load += new System.EventHandler(this.UserControl1_Load);
			this.ResumeLayout(false);

		}
		#endregion

		private void ToolMenu_OnClick(object sender, EventArgs e)
		{
			GrooveWebServicesV12Controls.ToolTreeNode ToolTreeNode = (GrooveWebServicesV12Controls.ToolTreeNode)TreeView.SelectedNode;

			System.Windows.Forms.MenuItem MenuItem = (System.Windows.Forms.MenuItem)sender;
			switch (MenuItem.Index)
			{
				//  View
				case 0:
				{
					GrooveWebServicesV12Helpers.Local.View
						(
						ToolTreeNode.Tool.Space.Identity,
						ToolTreeNode.Tool.URI
						);
					
					break;
				}

				//  View tool properties
				case 1:
				{
					GrooveWebServicesV12Helpers.Local.OpenToolPropertiesViewer(ToolTreeNode.Tool);

					break;

				}

				default:
				{
					System.Diagnostics.Debug.Assert(false, "Unknown menu item!");
					break;
				}
			}
		}

		private void SpaceMenu_OnClick(object sender, EventArgs e)
		{
			System.Windows.Forms.MenuItem MenuItem = (System.Windows.Forms.MenuItem)sender;
			GrooveWebServicesV12Controls.SpaceTreeNode SpaceTreeNode = (GrooveWebServicesV12Controls.SpaceTreeNode)TreeView.SelectedNode;
			GrooveWebServicesV12Helpers.Space Space = SpaceTreeNode.Space;

			switch (MenuItem.Index)
			{
				// View
				case 0:
				{
					GrooveWebServicesV12Helpers.Local.View
						(
						Space.Identity,
						Space.URI
						);

					break;
				}

				// Properties
				case 1:
				{
					GrooveWebServicesV12Helpers.Local.OpenSpacePropertiesViewer(Space);

					break;
				}

				default:
				{
					System.Diagnostics.Debug.Assert(false, "Unknown menu item: " + MenuItem.Index);
					break;
				}
			}
		}

		private void IdentityMenu_OnClick(object sender, EventArgs e)
		{
			GrooveWebServicesV12Controls.IdentityTreeNode IdentityTreeNode = (GrooveWebServicesV12Controls.IdentityTreeNode)TreeView.SelectedNode;
			GrooveWebServicesV12Helpers.Local.OpenVCardEditor(IdentityTreeNode.Identity);
		}

		private void AccountMenu_OnClick(object sender, EventArgs e)
		{
			System.Windows.Forms.MenuItem MenuItem = (System.Windows.Forms.MenuItem)sender;
			GrooveWebServicesV12Controls.AccountTreeNode AccountTreeNode = (GrooveWebServicesV12Controls.AccountTreeNode)TreeView.SelectedNode;
			GrooveWebServicesV12Helpers.Account Account = AccountTreeNode.Account;

			switch (MenuItem.Index)
			{
				// Activation Wizard
				case 0:
				{
					GrooveWebServicesV12Helpers.Local.OpenAccountSetupWizard(Account.Identities[0]);

					break;
				}

				// About
				case 1:
				{
					GrooveWebServicesV12Helpers.Local.OpenAboutGrooveDialog(Account.Identities[0]);

					break;
				}

				// Licenses
				case 2:
				{
					GrooveWebServicesV12Helpers.Local.OpenLicenseViewer(Account.Identities[0]);

					break;
				}

				// Communications
				case 3:
				{
					GrooveWebServicesV12Helpers.Local.OpenCommunicationsViewer(Account.Identities[0]);

					break;
				}

				// Preferences
				case 4:
				{
					GrooveWebServicesV12Helpers.Local.OpenPreferencesViewer(Account.Identities[0]);

					break;
				}

				default:
				{
					System.Diagnostics.Debug.Assert(false, "Unknown menu item: " + MenuItem.Index);
					break;
				}
			}
		}

		private void TreeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == System.Windows.Forms.MouseButtons.Right)
			{
				System.Windows.Forms.TreeNode TreeNode = TreeView.GetNodeAt(e.X, e.Y);
				if (TreeNode != null)
				{
					//  Remove existing menu items
					m_ContextMenu.MenuItems.Clear();

					System.Windows.Forms.MenuItem[] MenuItems = null;

					if (TreeNode is GrooveWebServicesV12Controls.ToolTreeNode)
					{
						MenuItems = new System.Windows.Forms.MenuItem[]
						{
							m_ViewToolMenuItem, m_ViewToolPropertiesMenuItem
						};
					}
					else if (TreeNode is GrooveWebServicesV12Controls.SpaceTreeNode)
					{
						MenuItems = new System.Windows.Forms.MenuItem[]
						{
							m_ViewSpaceMenuItem,
							m_ViewSpacePropertiesMenuItem
						};
					}
					else if (TreeNode is GrooveWebServicesV12Controls.IdentityTreeNode)
					{
						MenuItems = new System.Windows.Forms.MenuItem[]{m_EditVCardMenuItem};
					}
					else if (TreeNode is GrooveWebServicesV12Controls.AccountTreeNode)
					{
						MenuItems = new System.Windows.Forms.MenuItem[]
						{
							m_ViewAccountSetupMenuItem,
							m_ViewAboutGrooveDialogMenuItem,
							m_ViewLicensesDialogMenuItem,
							m_ViewCommunicationsMenuItem,
							m_ViewPreferencesMenuItem
						};
					}
					else
					{
						System.Diagnostics.Debug.Assert(false, "Unknown treenode type!");
					}

					//  Add corresponding menu items
					m_ContextMenu.MenuItems.AddRange(MenuItems);

					TreeView.SelectedNode = TreeNode;
					m_ContextMenu.Show(TreeView, new System.Drawing.Point(e.X, e.Y));
				}
			}
		}

		private void UserControl1_Load(object sender, System.EventArgs e)
		{
			PopulateTreeView();
		}

		private void PopulateTreeView()
		{
			TreeView.Nodes.Clear();

			if (this.DesignMode)
			{
				//  Create mockup tree
				System.Windows.Forms.TreeNode AccountTreeNode = new System.Windows.Forms.TreeNode("Account");
				AccountTreeNode.ImageIndex = 0;

				System.Windows.Forms.TreeNode IdentityTreeNode = new System.Windows.Forms.TreeNode("Identity");
				IdentityTreeNode.ImageIndex = 1;

				System.Windows.Forms.TreeNode SpaceTreeNode = new System.Windows.Forms.TreeNode("Space");
				SpaceTreeNode.ImageIndex = 2;

				if (AlwaysShowAccounts)
				{
					TreeView.Nodes.Add(AccountTreeNode);
					AccountTreeNode.Nodes.Add(IdentityTreeNode);
					IdentityTreeNode.Nodes.Add(SpaceTreeNode);
				}
				else if (AlwaysShowIdentities)
				{
					TreeView.Nodes.Add(IdentityTreeNode);
					IdentityTreeNode.Nodes.Add(SpaceTreeNode);
				}
				else
				{
					TreeView.Nodes.Add(SpaceTreeNode);
				}

				if (!HideCalendarTools)
				{
					System.Windows.Forms.TreeNode CalendarToolTreeNode = new System.Windows.Forms.TreeNode("Calendar Tool");
					CalendarToolTreeNode.ImageIndex = 3;
					SpaceTreeNode.Nodes.Add(CalendarToolTreeNode);
				}

				if (!HideDiscussionTools)
				{
					System.Windows.Forms.TreeNode DiscussionToolTreeNode = new System.Windows.Forms.TreeNode("Discussion Tool");
					DiscussionToolTreeNode.ImageIndex = 4;
					SpaceTreeNode.Nodes.Add(DiscussionToolTreeNode);
				}

				if (!HideFilesTools)
				{
					System.Windows.Forms.TreeNode FilesToolTreeNode = new System.Windows.Forms.TreeNode("Files Tool");
					FilesToolTreeNode.ImageIndex = 5;
					SpaceTreeNode.Nodes.Add(FilesToolTreeNode);
				}

				if (!HideFormsTools)
				{
					System.Windows.Forms.TreeNode FormsToolTreeNode = new System.Windows.Forms.TreeNode("Forms Tool");
					FormsToolTreeNode.ImageIndex = 13;
					SpaceTreeNode.Nodes.Add(FormsToolTreeNode);
				}

				TreeView.ExpandAll();
			}
			else
			{
				System.Windows.Forms.TreeNodeCollection NullTreeNodeCollection = null;

				GrooveWebServicesV12Helpers.Account[] Accounts = null;
				try
				{
					Accounts = GrooveWebServicesV12Helpers.Account.GetAccounts(m_Context);
				}
				catch (Exception ex)
				{
					TreeView.Nodes.Add("Unable to get accounts: " + ex.Message);
					return;
				}

				if ((Accounts.Length > 1) || m_AlwaysShowAccounts)
				{
					//  If multiple accounts, need to add account tree nodes
					foreach (GrooveWebServicesV12Helpers.Account Account in Accounts)
					{
						Application.DoEvents();
						AddAccountTreeNode(TreeView.Nodes, Account);
					}
				}
				else
				{
					//  Create one and only account node, but don't display it
					AddAccountTreeNode(NullTreeNodeCollection, Accounts[0]);

					GrooveWebServicesV12Helpers.Identity[] Identities = null;
					
					try
					{
						Identities = Accounts[0].Identities;
					}
					catch (Exception ex)
					{
						TreeView.Nodes.Add("Unable to get identities: " + ex.Message);
						return;
					}

					if ((Identities.Length > 1) || m_AlwaysShowIdentities)
					{
						//  If multiple identities, need to add identity tree nodes
						foreach (GrooveWebServicesV12Helpers.Identity Identity in Identities)
						{
							Application.DoEvents();
							AddIdentityTreeNode(TreeView.Nodes, Identity);
						}
					}
					else
					{
						//  Create one and only identity node, but don't display it
						AddIdentityTreeNode(NullTreeNodeCollection, Identities[0]);

						//  Save reference to current identity
						m_CurrentIdentity = Identities[0];

						//  Subscribe for space events

						//  -------------------------------------------------------------
						//  BIG HONKING NOTE:  Do not subscribe while any locks are held!
			
							m_CurrentIdentity.OnSpaceAddedEvent += new GrooveWebServicesV12Helpers.Identity.OnSpaceAddedDelegate(Identity_OnSpaceAdded);
							m_CurrentIdentity.OnSpaceRenamedEvent += new GrooveWebServicesV12Helpers.Identity.OnSpaceRenamedDelegate(Identity_OnSpaceRenamed);
							m_CurrentIdentity.OnSpaceRemovedEvent += new GrooveWebServicesV12Helpers.Identity.OnSpaceRemovedDelegate(Identity_OnSpaceRemoved);

						//  -------------------------------------------------------------

						foreach (GrooveWebServicesV12Helpers.Space Space in m_CurrentIdentity.StandardSpaces)
						{
							Application.DoEvents();
							AddSpaceTreeNode(TreeView.Nodes, Space);
						}
					}
				}
			}
		}

		private void AddAccountTreeNode(System.Windows.Forms.TreeNodeCollection i_TreeNodeCollection, GrooveWebServicesV12Helpers.Account i_Account)
		{
			GrooveWebServicesV12Controls.AccountTreeNode AccountTreeNode = null;

			lock (m_AccountTreeNodeSortedList)
			{
				//  Check for existing node, if found just exit now
				AccountTreeNode = (GrooveWebServicesV12Controls.AccountTreeNode)m_AccountTreeNodeSortedList[i_Account.URI];
				if (AccountTreeNode != null)
					return;

				AccountTreeNode = new GrooveWebServicesV12Controls.AccountTreeNode(i_Account);
				AccountTreeNode.Text = i_Account.Name;
				AccountTreeNode.ImageIndex = 0;

				//  Add new node to sorted list
				m_AccountTreeNodeSortedList[i_Account.URI] = AccountTreeNode;

				//  Add node to node collection
				if (i_TreeNodeCollection != null)
					i_TreeNodeCollection.Add(AccountTreeNode);
			}

			//  Iterate through identities and add tree nodes
			if (i_TreeNodeCollection != null)
			{
				GrooveWebServicesV12Helpers.Identity[] Identities = null;
				
				try
				{
					Identities = i_Account.Identities;
				}
				catch (Exception ex)
				{
					AccountTreeNode.Nodes.Add("Unable to get identities: " + ex.Message);
					return;
				}

				foreach (GrooveWebServicesV12Helpers.Identity Identity in Identities)
				{
					Application.DoEvents();
					AddIdentityTreeNode(AccountTreeNode.Nodes, Identity);
				}
			}
		}

		private void AddIdentityTreeNode(System.Windows.Forms.TreeNodeCollection i_TreeNodeCollection, GrooveWebServicesV12Helpers.Identity i_Identity)
		{
			GrooveWebServicesV12Controls.IdentityTreeNode IdentityTreeNode = null;

			lock (m_IdentityTreeNodeSortedList)
			{
				//  Check for existing node, if found just exit now
				IdentityTreeNode = (GrooveWebServicesV12Controls.IdentityTreeNode)m_IdentityTreeNodeSortedList[i_Identity.URI];
				if (IdentityTreeNode != null)
					return;

				IdentityTreeNode = new GrooveWebServicesV12Controls.IdentityTreeNode(i_Identity);
				IdentityTreeNode.Text = i_Identity.Name;
				IdentityTreeNode.ImageIndex = 1;

				//  Add new node to sorted list
				m_AccountTreeNodeSortedList[i_Identity.URI] = IdentityTreeNode;

				//  Add node to node collection
				if (i_TreeNodeCollection != null)
				{
					i_TreeNodeCollection.Add(IdentityTreeNode);
					
					//  Do one time initialization of identity tree node if URIs match
					if (i_Identity.URI == m_InitialIdentityURI)
					{
						TreeView.SelectedNode = IdentityTreeNode;
						m_InitialIdentityURI = null;
					}
				}

				//  Add new node to sort list
				m_IdentityTreeNodeSortedList[i_Identity.URI] = IdentityTreeNode;

				//  Add dummy node so that "+" is displayed
				IdentityTreeNode.Nodes.Add("DummyNode");

			}
		}

		private void AddSpaceTreeNode(System.Windows.Forms.TreeNodeCollection i_TreeNodeCollection, GrooveWebServicesV12Helpers.Space i_Space)
		{
			GrooveWebServicesV12Controls.SpaceTreeNode SpaceTreeNode = null;

			lock (m_SpaceTreeNodeSortedList)
			{
				//  Check for existing node, if found just exit now
				SpaceTreeNode = (GrooveWebServicesV12Controls.SpaceTreeNode)m_SpaceTreeNodeSortedList[i_Space.URI];
				if (SpaceTreeNode != null)
					return;

				SpaceTreeNode = new GrooveWebServicesV12Controls.SpaceTreeNode(i_Space);
				SpaceTreeNode.Text = i_Space.Name;
				if (i_Space.IsLocal)
					SpaceTreeNode.ImageIndex = 2;
				else
					SpaceTreeNode.ImageIndex = 10;
				
				i_TreeNodeCollection.Add(SpaceTreeNode);

				//  Do one time initialization of space tree node if URIs match
				if (i_Space.URI == m_InitialSpaceURI)
				{
					TreeView.SelectedNode = SpaceTreeNode;
					m_InitialSpaceURI = null;
				}

				//  Add new node to sorted list
				m_SpaceTreeNodeSortedList[i_Space.URI] = SpaceTreeNode;

				//  If space is local, add dummy node so that "+" is displayed
				if (i_Space.IsLocal)
					SpaceTreeNode.Nodes.Add("DummyNode");
			}
		}

		private void AddToolTreeNode(System.Windows.Forms.TreeNodeCollection i_TreeNodeCollection, GrooveWebServicesV12Helpers.Tool i_Tool)
		{
			GrooveWebServicesV12Controls.ToolTreeNode ToolTreeNode = null;

			lock (m_ToolTreeNodeSortedList)
			{
				//  Check for existing node, if found just exit now
				ToolTreeNode = (GrooveWebServicesV12Controls.ToolTreeNode)m_ToolTreeNodeSortedList[i_Tool.URI];
				if (ToolTreeNode != null)
					return;

				string ToolType = i_Tool.Type;
				int ImageIndex = - 1;

				switch (ToolType)
				{
					case GrooveWebServicesV12Helpers.Shared.GROOVE_CALENDAR_TOOL_SUPPORTED_TYPE:
					{
						//  Check to see if we should hide this tool
						if ((m_HideToolsBitMask & HIDE_CALENDAR_TOOLS) == HIDE_CALENDAR_TOOLS)
							return;

						ImageIndex = 3;

						break;
					}

					case GrooveWebServicesV12Helpers.Shared.GROOVE_DISCUSSION_TOOL_SUPPORTED_TYPE:
					{
						//  Check to see if we should hide this tool
						if ((m_HideToolsBitMask & HIDE_DISCUSSION_TOOLS) == HIDE_DISCUSSION_TOOLS)
							return;

						ImageIndex = 4;

						break;
					}

					case GrooveWebServicesV12Helpers.Shared.GROOVE_FILES_TOOL_SUPPORTED_TYPE:
                    case GrooveWebServicesV12Helpers.Shared.GROOVE_SHAREPOINT_FILES_TOOL_SUPPORTED_TYPE:
					{
						//  Check to see if we should hide this tool
						if ((m_HideToolsBitMask & HIDE_FILES_TOOLS) == HIDE_FILES_TOOLS)
							return;

						ImageIndex = 5;

						break;
					}

					case GrooveWebServicesV12Helpers.Shared.GROOVE_FORMS_TOOL_SUPPORTED_TYPE:
                    case GrooveWebServicesV12Helpers.Shared.GROOVE_FORMS2_TOOL_SUPPORTED_TYPE:
                    case GrooveWebServicesV12Helpers.Shared.GROOVE_INFOPATH_FORMS_TOOL_SUPPORTED_TYPE:
					{
						//  Check to see if we should hide this tool
						if ((m_HideToolsBitMask & HIDE_FORMS_TOOLS) == HIDE_FORMS_TOOLS)
							return;

						ImageIndex = 13;

						break;
					}

					default:
					{
						System.Diagnostics.Debug.WriteLine("Unknown tool type found: " + ToolType);
						return;
					}
				}

				ToolTreeNode = new GrooveWebServicesV12Controls.ToolTreeNode(i_Tool);
				ToolTreeNode.Text = i_Tool.Name;
				ToolTreeNode.ImageIndex = ImageIndex;
		
				i_TreeNodeCollection.Add(ToolTreeNode);

				//  Add new node to sorted list
				m_ToolTreeNodeSortedList[i_Tool.URI] = ToolTreeNode;
			}
		}

		private void RenameSpaceTreeNode(string i_SpaceURI, string i_SpaceName)
		{
			lock (m_SpaceTreeNodeSortedList)
			{
				//  Check for existing node, if not found just exit now
				GrooveWebServicesV12Controls.SpaceTreeNode SpaceTreeNode = (GrooveWebServicesV12Controls.SpaceTreeNode)m_SpaceTreeNodeSortedList[i_SpaceURI];
				if (SpaceTreeNode == null)
					return;

				SpaceTreeNode.Text = i_SpaceName;
			}
		}

		private void RenameToolTreeNode(string i_ToolURI, string i_ToolName)
		{
			lock (m_ToolTreeNodeSortedList)
			{
				//  Check for existing node, if not found just exit now
				GrooveWebServicesV12Controls.ToolTreeNode ToolTreeNode = (GrooveWebServicesV12Controls.ToolTreeNode)m_ToolTreeNodeSortedList[i_ToolURI];
				if (ToolTreeNode == null)
					return;

				ToolTreeNode.Text = i_ToolName;
			}
		}

		private void RemoveTreeNode(System.Collections.SortedList i_SortedList, string i_URI)
		{
			lock (i_SortedList)
			{
				//  Check for existing node, if not found just exit now
				if (i_SortedList[i_URI] == null)
					return;

				//  Remove tree node
				System.Windows.Forms.TreeNode TreeNode = (System.Windows.Forms.TreeNode)i_SortedList[i_URI];
				TreeNode.Remove();

				//  Remove node from sorted list
				i_SortedList.Remove(i_URI);
			}
		}

		#region Space Event Handlers

		private void Identity_OnSpaceAdded(GrooveWebServicesV12Helpers.Space i_Space)
		{
			System.Diagnostics.Debug.WriteLine("OnSpacedAdded: " + i_Space.Name);
			
			lock (m_SpaceTreeNodeSortedList)
			{
				//  Check for existing node, if found just exit now
				if (m_SpaceTreeNodeSortedList[i_Space.URI] != null)
					return;

				//  Get identity tree node
				GrooveWebServicesV12Controls.IdentityTreeNode IdentityTreeNode = (GrooveWebServicesV12Controls.IdentityTreeNode)m_IdentityTreeNodeSortedList[i_Space.Identity.URI];
				
				//  Get appropriate node collection
				System.Windows.Forms.TreeNodeCollection TreeNodeCollection = IdentityTreeNode.Nodes;
				if (!IdentityTreeNode.IsVisible)
					TreeNodeCollection = TreeView.Nodes;

				//  Asynchronously add space tree node
				object[] Args = {TreeNodeCollection, i_Space};
				BeginInvoke(m_AddSpaceTreeNodeDelegate, Args);
			}
		}

		private void Identity_OnSpaceRenamed(GrooveWebServicesV12Helpers.Space i_Space)
		{
			System.Diagnostics.Debug.WriteLine("OnSpacedRenamed: " + i_Space.Name);

			lock (m_SpaceTreeNodeSortedList)
			{
				//  Check for existing node, if not found just exit now
				if (m_SpaceTreeNodeSortedList[i_Space.URI] == null)
					return;

				//  --------------------------------------------------------------------------------
				//  HACK ALERT:  It's possible that a new space was created and it is triggering the
				//               rename event.  For this reason, we compare the IsLocal property to
				//               see if they mismatch

					GrooveWebServicesV12Controls.SpaceTreeNode SpaceTreeNode = (GrooveWebServicesV12Controls.SpaceTreeNode)m_SpaceTreeNodeSortedList[i_Space.URI];
					bool Mismatch = (SpaceTreeNode.Space.IsLocal != i_Space.IsLocal);
				
				//  --------------------------------------------------------------------------------

				object[] Args = null;

				if (!Mismatch)
				{
					//  Asynchronously rename space tree node
					Args = new object[]{i_Space.URI, i_Space.Name};
					BeginInvoke(m_RenameSpaceTreeNodeDelegate, Args);

					return;
				}

				//  -----------------------------------------------------------------------------
				//  HACK ALERT:  Mismatch detected, so delete existing space node and add new one

					//  Asynchronously remove space tree node
					Args = new object[]{m_SpaceTreeNodeSortedList, i_Space.URI};
					BeginInvoke(m_RemoveTreeNodeDelegate, Args);

					//  Get identity tree node
					GrooveWebServicesV12Controls.IdentityTreeNode IdentityTreeNode = (GrooveWebServicesV12Controls.IdentityTreeNode)m_IdentityTreeNodeSortedList[i_Space.Identity.URI];
				
					//  Get appropriate node collection
					System.Windows.Forms.TreeNodeCollection TreeNodeCollection = IdentityTreeNode.Nodes;
					if (!IdentityTreeNode.IsVisible)
						TreeNodeCollection = TreeView.Nodes;

					//  Asynchronously add space tree node
					Args = new object[]{TreeNodeCollection, i_Space};
					BeginInvoke(m_AddSpaceTreeNodeDelegate, Args);

				//  -----------------------------------------------------------------------------
			}
		}

		private void Identity_OnSpaceRemoved(string i_SpaceURI)
		{
			System.Diagnostics.Debug.WriteLine("OnSpacedRemoved: " + i_SpaceURI);

			lock (m_SpaceTreeNodeSortedList)
			{
				//  Check for existing node, if not found just exit now
				if (m_SpaceTreeNodeSortedList[i_SpaceURI] == null)
					return;
			
				//  Asynchronously remove space tree node
				object[] Args = {m_SpaceTreeNodeSortedList, i_SpaceURI};
				BeginInvoke(m_RemoveTreeNodeDelegate, Args);
			}
		}

		#endregion

		#region Tool Event Handlers

		private void Space_OnToolAdded(GrooveWebServicesV12Helpers.Tool i_Tool)
		{
			System.Diagnostics.Debug.WriteLine("OnToolAdded: " + i_Tool.Name);

			lock (m_ToolTreeNodeSortedList)
			{
				//  Check for existing node, if found just exit now
				if (m_ToolTreeNodeSortedList[i_Tool.URI] != null)
					return;

				//  Get space tree node

				//  ---------------------------------------------------------
				//  HACK ALERT:  Only way to get space URI is by manipulating
				//  tool URI

					string URI = i_Tool.URI;			
					int Index = i_Tool.URI.IndexOf("/ToolContainer");
					
					if (Index != -1)
					{
						URI = i_Tool.URI.Substring(0, Index);
						URI = URI.Replace("/Tools/", "/Spaces/");
					}

				//  ---------------------------------------------------------

				GrooveWebServicesV12Controls.SpaceTreeNode SpaceTreeNode = (GrooveWebServicesV12Controls.SpaceTreeNode)m_SpaceTreeNodeSortedList[URI];

				//  Asynchronously add Tool tree node
				object[] Args = {SpaceTreeNode.Nodes, i_Tool};
				BeginInvoke(m_AddToolTreeNodeDelegate, Args);
			}
		}

		private void Space_OnToolRenamed(GrooveWebServicesV12Helpers.Tool i_Tool)
		{
			System.Diagnostics.Debug.WriteLine("OnToolRenamed: " + i_Tool.Name);

			lock (m_ToolTreeNodeSortedList)
			{
				//  Check for existing node, if not found just exit now
				if (m_ToolTreeNodeSortedList[i_Tool.URI] == null)
					return;

				//  Asynchronously rename Tool tree node
				object[] Args = {i_Tool.URI, i_Tool.Name};
				BeginInvoke(m_RenameToolTreeNodeDelegate, Args);
			}
		}

		private void Space_OnToolRemoved(string i_ToolURI)
		{
			System.Diagnostics.Debug.WriteLine("OnToolRemoved: " + i_ToolURI);

			lock (m_ToolTreeNodeSortedList)
			{
				//  Check for existing node, if not found just exit now
				if (m_ToolTreeNodeSortedList[i_ToolURI] == null)
					return;

				//  Asynchronously remove space tree node
				object[] Args = {m_ToolTreeNodeSortedList, i_ToolURI};
				BeginInvoke(m_RemoveTreeNodeDelegate, Args);
			}
		}

		#endregion

		private void TreeView_BeforeSelect(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
		{
			//  If multiple identities either via same account or different
			//  accounts, need to set current identity
			if (e.Node is GrooveWebServicesV12Controls.ToolTreeNode)
			{
				GrooveWebServicesV12Controls.ToolTreeNode ToolTreeNode = (GrooveWebServicesV12Controls.ToolTreeNode)e.Node;

				if (ToolTreeNode.Parent != null)
				{
					GrooveWebServicesV12Controls.SpaceTreeNode SpaceTreeNode = (GrooveWebServicesV12Controls.SpaceTreeNode)ToolTreeNode.Parent;

					if (SpaceTreeNode.Parent != null)
					{
						GrooveWebServicesV12Controls.IdentityTreeNode IdentityTreeNode = (GrooveWebServicesV12Controls.IdentityTreeNode)SpaceTreeNode.Parent;

						//  Save reference to current identity
						m_CurrentIdentity = IdentityTreeNode.Identity;
					}
				}
			}
		}

		private void TreeView_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
		{
			//  Show wait cursor
			this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
			System.Windows.Forms.Cursor.Show();

			try
			{
				//  Check for dummy node - if it's not there, then
				//  we have already populated children nodes
				if (e.Node.Nodes[0].Text != "DummyNode")
					return;

				//  Clear dummy node
				e.Node.Nodes.Clear();

				if (e.Node is GrooveWebServicesV12Controls.IdentityTreeNode)
				{
					GrooveWebServicesV12Controls.IdentityTreeNode IdentityTreeNode = (GrooveWebServicesV12Controls.IdentityTreeNode)e.Node;

					//  Subscribe for space events

					//  -------------------------------------------------------------
					//  BIG HONKING NOTE:  Do not subscribe while any locks are held!
			
						IdentityTreeNode.Identity.OnSpaceAddedEvent += new GrooveWebServicesV12Helpers.Identity.OnSpaceAddedDelegate(Identity_OnSpaceAdded);
						IdentityTreeNode.Identity.OnSpaceRenamedEvent += new GrooveWebServicesV12Helpers.Identity.OnSpaceRenamedDelegate(Identity_OnSpaceRenamed);
						IdentityTreeNode.Identity.OnSpaceRemovedEvent += new GrooveWebServicesV12Helpers.Identity.OnSpaceRemovedDelegate(Identity_OnSpaceRemoved);

					//  -------------------------------------------------------------

					//  Iterate through spaces and add tree nodes
					GrooveWebServicesV12Helpers.Space[] Spaces = null;
			
					try
					{
						Spaces = IdentityTreeNode.Identity.StandardSpaces;
					}
					catch (Exception ex)
					{
						IdentityTreeNode.Nodes.Add("Unable to get spaces: " + ex.Message);
						return;
					}

					foreach (GrooveWebServicesV12Helpers.Space Space in Spaces)
					{
						Application.DoEvents();
						AddSpaceTreeNode(IdentityTreeNode.Nodes, Space);
					}
				}
				else if (e.Node is GrooveWebServicesV12Controls.SpaceTreeNode)
				{
					GrooveWebServicesV12Controls.SpaceTreeNode SpaceTreeNode = (GrooveWebServicesV12Controls.SpaceTreeNode)e.Node;

					//  Subscribe for tool events

					//  -------------------------------------------------------------
					//  BIG HONKING NOTE:  Do not subscribe while any locks are held!

					SpaceTreeNode.Space.OnToolAddedEvent += new GrooveWebServicesV12Helpers.Space.OnToolAddedDelegate(Space_OnToolAdded);
					SpaceTreeNode.Space.OnToolRenamedEvent += new GrooveWebServicesV12Helpers.Space.OnToolRenamedDelegate(Space_OnToolRenamed);
					SpaceTreeNode.Space.OnToolRemovedEvent += new GrooveWebServicesV12Helpers.Space.OnToolRemovedDelegate(Space_OnToolRemoved);

					//  -------------------------------------------------------------

					//  Iterate through tools and add tree nodes
					GrooveWebServicesV12Helpers.Tool[] Tools = null;
			
					try
					{
						//  Create and populate array list with supported types
						System.Collections.ArrayList SupportedTypesArrayList = new System.Collections.ArrayList();

                        if ((m_HideToolsBitMask & HIDE_FILES_TOOLS) != HIDE_FILES_TOOLS)
                        {
                            SupportedTypesArrayList.Add(GrooveWebServicesV12Helpers.Shared.GROOVE_FILES_TOOL_SUPPORTED_TYPE);
                            SupportedTypesArrayList.Add(GrooveWebServicesV12Helpers.Shared.GROOVE_SHAREPOINT_FILES_TOOL_SUPPORTED_TYPE);
                        }

						if ((m_HideToolsBitMask & HIDE_DISCUSSION_TOOLS) != HIDE_DISCUSSION_TOOLS)
							SupportedTypesArrayList.Add(GrooveWebServicesV12Helpers.Shared.GROOVE_DISCUSSION_TOOL_SUPPORTED_TYPE);

						if ((m_HideToolsBitMask & HIDE_CALENDAR_TOOLS) != HIDE_CALENDAR_TOOLS)
							SupportedTypesArrayList.Add(GrooveWebServicesV12Helpers.Shared.GROOVE_CALENDAR_TOOL_SUPPORTED_TYPE);

                        if ((m_HideToolsBitMask & HIDE_FORMS_TOOLS) != HIDE_FORMS_TOOLS)
                        {
                            SupportedTypesArrayList.Add(GrooveWebServicesV12Helpers.Shared.GROOVE_FORMS_TOOL_SUPPORTED_TYPE);
                            SupportedTypesArrayList.Add(GrooveWebServicesV12Helpers.Shared.GROOVE_FORMS2_TOOL_SUPPORTED_TYPE);
                            SupportedTypesArrayList.Add(GrooveWebServicesV12Helpers.Shared.GROOVE_INFOPATH_FORMS_TOOL_SUPPORTED_TYPE);
                        }

						//  Create array from array list
						string[] SupportedTypes = (string[])SupportedTypesArrayList.ToArray(typeof(string));

						Tools = SpaceTreeNode.Space.GetToolsBySupportedTypes(SupportedTypes);
					}
					catch (Exception ex)
					{
						SpaceTreeNode.Nodes.Add("Unable to get tools: " + ex.Message);
						return;
					}

					foreach (GrooveWebServicesV12Helpers.Tool Tool in Tools)
					{
						Application.DoEvents();

						AddToolTreeNode(SpaceTreeNode.Nodes, Tool);
					}
				}
			}
			finally
			{
				//  Restore default cursor
				this.Cursor = System.Windows.Forms.Cursors.Default;
				System.Windows.Forms.Cursor.Show();
			}
		}
	}
}
